import React, { useImperativeHandle, useReducer, useEffect } from 'react';
import { View } from '@tarojs/components';
import { FormContext } from './FormContext';
import { FormProps, FormInstance } from './types';

// 状态 reducer
function formReducer(state, action) {
  switch (action.type) {
    case 'UPDATE_FIELD':
      return {
        ...state,
        formData: {
          ...state.formData,
          [action.name]: action.value,
        },
      };
    case 'SET_FIELDS_VALUE':
      return {
        ...state,
        formData: {
          ...state.formData,
          ...action.values,
        },
      };
    case 'SET_ERROR':
      return {
        ...state,
        errors: {
          ...state.errors,
          [action.name]: action.message,
        },
      };
    case 'CLEAR_ERRORS':
      return {
        ...state,
        errors: {},
      };
    case 'RESET_FIELDS':
      return {
        formData: action.initialValues || {},
        errors: {},
      };
    default:
      return state;
  }
}

const Form = React.forwardRef<FormInstance, FormProps>((props, ref) => {
  const { initialValues = {}, onFinish, onFinishFailed, children } = props;

  const [state, dispatch] = useReducer(formReducer, {
    formData: initialValues,
    errors: {},
  });

  const fieldsRef = React.useRef<Set<string>>(new Set());

  // 注册表单项
  const registerField = (name: string) => {
    fieldsRef.current.add(name);
  };

  // 注销表单项
  const unregisterField = (name: string) => {
    fieldsRef.current.delete(name);
  };

  // 更新字段值
  const updateField = (name: string, value: any) => {
    dispatch({ type: 'UPDATE_FIELD', name, value });

    // 如果有错误，清除该字段的错误
    if (state.errors[name]) {
      dispatch({ type: 'SET_ERROR', name, message: '' });
    }
  };

  // 表单方法
  const formInstance: FormInstance = {
    getFieldsValue: () => ({ ...state.formData }),
    setFieldsValue: (values: Record<string, any>) => {
      dispatch({ type: 'SET_FIELDS_VALUE', values });
    },
    resetFields: () => {
      dispatch({ type: 'RESET_FIELDS', initialValues });
    },
    validateFields: async () => {
      // 这里实现验证逻辑
      return new Promise((resolve, reject) => {
        const errors = {};
        let hasError = false;

        fieldsRef.current.forEach(name => {
          // 简单的必填验证
          if (!state.formData[name] && state.formData[name] !== 0) {
            errors[name] = '该字段是必填的';
            hasError = true;
          }
        });

        if (hasError) {
          // 设置错误状态
          Object.keys(errors).forEach(name => {
            dispatch({ type: 'SET_ERROR', name, message: errors[name] });
          });
          reject(errors);
          onFinishFailed && onFinishFailed(errors);
        } else {
          resolve(state.formData);
          onFinish && onFinish(state.formData);
        }
      });
    },
  };

  // 暴露表单实例给父组件
  useImperativeHandle(ref, () => formInstance, [state.formData, state.errors]);

  // 提供上下文
  const contextValue = {
    formData: state.formData,
    errors: state.errors,
    updateField,
    registerField,
    unregisterField,
  };

  return (
    <FormContext.Provider value={contextValue}>
      <View className='taro-form'>{children}</View>
    </FormContext.Provider>
  );
});

export default Form;
